﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AAA.DesignPattern.Observer;
using AAA.Meta.Quote.Data;
using AAA.DataSource;
using AAA.TradeLanguage.Data;
using AAA.DesignPattern.Singleton;
using AAA.Base.Util;

namespace AAA.TradeLanguage
{
    /**
     *  當新價位進來時, 計算目前的各選擇權價位, 當日期有變化時, 計算熱門月及次月的月份 
     **/
    public class ContractUpdate : IVariableCalculate
    {
        private float _fPreviousAtMoneyPrice;
        private string _strStartDate;
        private ITradingRule _tradingRule;

        public ContractUpdate()
        {
            _fPreviousAtMoneyPrice = 0;
            _strStartDate = "19000101";
            _tradingRule = new DefaultTradingRule();
        }

        #region IObserver 成員

        public void Update(object oSource, IMessageInfo miMessage)
        {
            float fCurrentPrice = 0;
            float fAtTheMoneyPrice;
            ContractInfo hotContract;
            ContractInfo optionsContract;
            ContractInfo atMoneyContract;

            try
            {
/*
                if (DateTime.Now.ToString("yyyyMMdd") != _strStartDate)
                {
                    _strStartDate = DateTime.Now.ToString("yyyyMMdd");
                    hotContract = SymbolUtil.HotContract(DateTime.Now);

                    SystemParameter.Parameter[DataSourceConstants.HOT_CONTRACT] = hotContract;
                    SystemParameter.Parameter[DataSourceConstants.NEXT_MONTH_CONTRACT] = SymbolUtil.NextMonthContract(hotContract);
                }
*/
                switch (miMessage.MessageSubject)
                {
                    case DataSourceConstants.TICK_RECEIVE:
                        fCurrentPrice = ((TickData)miMessage.Message).Price;
                        break;
                    case DataSourceConstants.BAR_RECEIVE:
                        fCurrentPrice = ((BarData)miMessage.Message).Close;
                        break;
                }

                fAtTheMoneyPrice = SymbolUtil.AtTheMoneyPrice(fCurrentPrice);

                _tradingRule.CreateBasicContractInfo(DateTime.Now, fCurrentPrice);
                SystemParameter.Parameter[DataSourceConstants.HOT_CONTRACT] = _tradingRule.GetContractInfo(DataSourceConstants.HOT_CONTRACT);
                SystemParameter.Parameter[DataSourceConstants.NEXT_MONTH_CONTRACT] = _tradingRule.GetContractInfo(DataSourceConstants.NEXT_MONTH_CONTRACT);
                SystemParameter.Parameter[DataSourceConstants.CALL_AT_THE_MONEY] = _tradingRule.GetContractInfo(DataSourceConstants.CALL_AT_THE_MONEY);
                SystemParameter.Parameter[DataSourceConstants.CALL_IN_THE_MONEY] = _tradingRule.GetContractInfo(DataSourceConstants.CALL_IN_THE_MONEY);
                SystemParameter.Parameter[DataSourceConstants.CALL_IN_THE_MONEY] = _tradingRule.GetContractInfo(DataSourceConstants.CALL_IN_THE_MONEY);
                SystemParameter.Parameter[DataSourceConstants.PUT_AT_THE_MONEY] = _tradingRule.GetContractInfo(DataSourceConstants.PUT_AT_THE_MONEY);
                SystemParameter.Parameter[DataSourceConstants.PUT_IN_THE_MONEY] = _tradingRule.GetContractInfo(DataSourceConstants.PUT_IN_THE_MONEY);
                SystemParameter.Parameter[DataSourceConstants.PUT_OUT_OF_THE_MONEY] = _tradingRule.GetContractInfo(DataSourceConstants.PUT_OUT_OF_THE_MONEY);
                
/*
                if (fAtTheMoneyPrice != _fPreviousAtMoneyPrice)
                {
                    // Generate Call Contract;
                    atMoneyContract = ((ContractInfo)SystemParameter.Parameter[DataSourceConstants.HOT_CONTRACT]).Clone();
                    atMoneyContract.ExecutePrice = fAtTheMoneyPrice;
                    atMoneyContract.SymbolType = SymbolTypeEnum.Call;
                    SystemParameter.Parameter[DataSourceConstants.CALL_AT_THE_MONEY] = atMoneyContract;

                    optionsContract = atMoneyContract.Clone();
                    optionsContract.ExecutePrice = SymbolUtil.ShiftExecutePrice(fAtTheMoneyPrice, -1);
                    SystemParameter.Parameter[DataSourceConstants.CALL_IN_THE_MONEY] = optionsContract;

                    optionsContract = atMoneyContract.Clone();
                    optionsContract.ExecutePrice = SymbolUtil.ShiftExecutePrice(fAtTheMoneyPrice, 1);
                    SystemParameter.Parameter[DataSourceConstants.CALL_OUT_OF_THE_MONEY] = optionsContract;
                    // Generate Put Contract;
                    atMoneyContract = ((ContractInfo)SystemParameter.Parameter[DataSourceConstants.HOT_CONTRACT]).Clone();
                    atMoneyContract.ExecutePrice = fAtTheMoneyPrice;
                    atMoneyContract.SymbolType = SymbolTypeEnum.Put;
                    SystemParameter.Parameter[DataSourceConstants.PUT_AT_THE_MONEY] = atMoneyContract;

                    optionsContract = atMoneyContract.Clone();
                    optionsContract.ExecutePrice = SymbolUtil.ShiftExecutePrice(fAtTheMoneyPrice, 1);
                    SystemParameter.Parameter[DataSourceConstants.PUT_IN_THE_MONEY] = optionsContract;

                    optionsContract = atMoneyContract.Clone();
                    optionsContract.ExecutePrice = SymbolUtil.ShiftExecutePrice(fAtTheMoneyPrice, -1);
                    SystemParameter.Parameter[DataSourceConstants.PUT_OUT_OF_THE_MONEY] = optionsContract;
                    _fPreviousAtMoneyPrice = fAtTheMoneyPrice;
                }
*/
            }
            catch (Exception ex)
            {

            }
        }

        #endregion
    }
}
